using System.Linq;
using System.Threading.Tasks;
using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Linq;
using Vecen.BangChuang.Authorization.Roles;
using Vecen.BangChuang.Validation;

namespace Vecen.BangChuang.Authorization.Users {
    public class UserStore: AbpUserStore<Role, User> {

        public UserStore(IUnitOfWorkManager unitOfWorkManager,
            IRepository<User, long> userRepository,
            IRepository<Role> roleRepository,
            IAsyncQueryableExecuter asyncQueryableExecuter,
            IRepository<UserRole, long> userRoleRepository,
            IRepository<UserLogin, long> userLoginRepository,
            IRepository<UserClaim, long> userClaimRepository,
            IRepository<UserPermissionSetting, long> userPermissionSettingRepository): base(unitOfWorkManager,
            userRepository, roleRepository, asyncQueryableExecuter, userRoleRepository, userLoginRepository,
            userClaimRepository, userPermissionSettingRepository) { }

        public override async Task<User> FindByNameOrEmailAsync(string userNameOrEmailAddress) {
            var user = base.FindByNameOrEmailAsync(userNameOrEmailAddress);
            if(user == null) {
                return await Task.Run(() => {
                    return Users.FirstOrDefault(c => c.PhoneNumber == userNameOrEmailAddress);
                });
            }
            return null;
        }

        public override async Task<User> FindByNameOrEmailAsync(int? tenantId, string userNameOrEmailAddress) {
            if(userNameOrEmailAddress.Any(c => c.Equals('@'))) {
                return await UserRepository.FirstOrDefaultAsync(
                    c => c.EmailAddress == userNameOrEmailAddress && c.TenantId == tenantId);
            }
            if(ValidationHelper.IsMobilePhone(userNameOrEmailAddress)) {
                return await UserRepository.FirstOrDefaultAsync(
                    c => c.PhoneNumber == userNameOrEmailAddress && c.TenantId == tenantId);
            }
            return await UserRepository.FirstOrDefaultAsync(
                c => c.UserName == userNameOrEmailAddress && c.TenantId == tenantId);

        }
    }
}